﻿/*
 程琳  MicroHard
 创建时间:2012-10-7
 修改时间:2012-10-7
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microhard.Permission.Interface;
using Microhard.Permission.Models;
using Microhard.Permission;
using Telerik.Web.Mvc.UI;
using Microhard.Core.DBUtility;
using Microhard.Core;

namespace Microhard.Permission_MembershipImpl
{
    public class GroupImpl : IGroup
    {
        private void GetSubGroup(MicroHard_Group group, ref Permission.Models.Group modelOrg)
        {
            if (group.GroupsChild == null || group.GroupsChild.Count == 0)
            {
                return;
            }
            modelOrg.SubOrgs = new List<Permission.Models.Group>();
            foreach (var o in group.GroupsChild)
            {
                var tmpModelOrg = o.ToModel();
                GetSubGroup(o, ref tmpModelOrg);
                modelOrg.SubOrgs.Add(tmpModelOrg);
            }
        }
 

        #region IRepository<Group> Members

        public ExecutedResult Add(Group model)
        {
            ExecutedResult rtn = new ExecutedResult();
            var entity = model.ToEntity();
            entity.OrgID = Guid.NewGuid();
            entity.CreateTime = DateTime.Now;
            if (entity.ParentOrgID == Guid.Empty)
            {
                entity.ParentOrgID = null;
            }
            MicrohardOUGDBDataContext db = new MicrohardOUGDBDataContext();
            db.MicroHard_Groups.InsertOnSubmit(entity);
            try
            {
                db.SubmitChanges();
                rtn.Scope.IsSysManage = true;
            }
            catch (Exception ex)
            {
                rtn.ErrorMsg.Add("GroupImpl.Add","添加组失败，请联系系统管理员");
                Log.Error("GroupImpl.Add", ex);
            }
            return rtn;
        }

        public ExecutedResult Update(Group model)
        {
            ExecutedResult rtn = new ExecutedResult();
            rtn.ErrorMsg.Add("GroupImpl.Update", "添加组失败，请联系系统管理员");
            MicrohardOUGDBDataContext db = new MicrohardOUGDBDataContext();
            var theOrg = db.MicroHard_Groups.SingleOrDefault(o => o.OrgID == model.ID);
            if (theOrg != null)
            {
                theOrg.OrgName = model.Name;
                theOrg.CreateTime = DateTime.Now;
                theOrg.ManagerID = db.aspnet_Users.SingleOrDefault(u => u.LoweredUserName == model.Manager.UserName.ToLower()).UserId;
                try
                {
                    db.SubmitChanges();
                    rtn.ErrorMsg.Clear();
                }
                catch (Exception ex)
                {
                    Log.Error("组织机构修改失败", ex);
                }
            }
            return rtn;
        }

        public ExecutedResult Delete(List<Guid> ids)
        {
            ExecutedResult rtn = new ExecutedResult();
            if (ids == null)
                return rtn;
            MicrohardOUGDBDataContext db = new MicrohardOUGDBDataContext();
            var theOrg = db.MicroHard_Groups.SingleOrDefault(o => o.OrgID == ids.First());
            if (theOrg == null)
            {
                return rtn;
            }
            if (theOrg.GroupsChild != null && theOrg.GroupsChild.Count > 0)
            {
                rtn.ErrorMsg.Add("GroupImpl.Delete", "此组包含子组，无法删除，请先删除子组");
                return rtn;
            }
            if (theOrg.MicroHard_EntitiesInGroups != null && theOrg.MicroHard_EntitiesInGroups.Count > 0)
            {
                rtn.ErrorMsg.Add("GroupImpl.Delete", "此组包含用户，无法删除，请先删除用户");
                return rtn;
            }
            //是否被使用
            if (theOrg.MicroHard_EntitiesInGroups != null && theOrg.MicroHard_EntitiesInGroups.Count > 0)
            {
                rtn.ErrorMsg.Add("GroupImpl.Delete", "此组正在使用中，无法删除");
                return rtn;
            }
            db.MicroHard_Groups.DeleteOnSubmit(theOrg);
            try
            {
                db.SubmitChanges();
            }
            catch (Exception ex)
            {
                Log.Error("GroupImpl.Delete", ex);
            }
            return rtn;
        }

        public Group GetModelByID(Guid id)
        {
            MicrohardOUGDBDataContext db = new MicrohardOUGDBDataContext();
            var entity = db.MicroHard_Groups.SingleOrDefault(o => o.OrgID == id);
            var rtn = entity.ToModel();
            rtn.SubOrgs = entity.GroupsChild.Select(j => j.ToModel()).ToList();
            var manager = db.aspnet_Users.SingleOrDefault(u => u.UserId == entity.ManagerID);
            rtn.Parent = entity.GroupParent.ToModel();
            if (manager != null)
            {
                rtn.Manager = manager.ToModel();
            }
            return rtn;
        }

        public List<Group> Query(Group Model, int pageIndex, int pageSize, out int totalCount)
        {
            throw new NotImplementedException();
        }

        public List<Group> Query(Group Model)
        {
            List<Permission.Models.Group> rtn = new List<Permission.Models.Group>();

            MicrohardOUGDBDataContext db = new MicrohardOUGDBDataContext();
            var list = db.MicroHard_Groups.Where(p => p.ParentOrgID == null).ToList();
            foreach (var o in list)
            {
                Permission.Models.Group tmpOrg = o.ToModel();
                GetSubGroup(o, ref tmpOrg);
                rtn.Add(tmpOrg);
            }
            return rtn;
        }

        public ExecutedResult Delete(Group models)
        {
            throw new NotImplementedException();
        }
        #endregion


        #region IGroup Members

        public List<Group> GetAllWithNoStruct()
        {
            MicrohardOUGDBDataContext db = new MicrohardOUGDBDataContext();
            return db.MicroHard_Groups.Select(g => g.ToModel()).ToList();
        }


        public ExecutedResult AddUserInGroup(Guid userID, List<Guid> groupIDs)
        {
            ExecutedResult rtn = new ExecutedResult();
            MicrohardOUGDBDataContext db = new MicrohardOUGDBDataContext();
            List<MicroHard_EntitiesInGroup> toAdd = new List<MicroHard_EntitiesInGroup>();
            foreach (var gId in groupIDs)
            {
                MicroHard_EntitiesInGroup add = new MicroHard_EntitiesInGroup
                {
                    OrgUserID = Guid.NewGuid(),
                    CreateTime = DateTime.Now,
                    EntityID = userID,
                    EntityType = (int)OwnerIDType.User,
                    OrgID = gId
                };
                toAdd.Add(add);
            }
            db.MicroHard_EntitiesInGroups.InsertAllOnSubmit(toAdd);
            try
            {
                db.SubmitChanges();
            }
            catch (Exception ex)
            {
                rtn.ErrorMsg.Add("GroupImpl.AddUserInGroup", "添加用户到组失败，请联系系统管理员");
                Log.Error("GroupImpl.AddUserInGroup",ex);
            }
            return rtn;
        }

        public ExecutedResult DeleteUserInGroup(Guid userID, List<Guid> groupIDsToDelete)
        {
            ExecutedResult rtn = new ExecutedResult();
            MicrohardOUGDBDataContext db = new MicrohardOUGDBDataContext();
            var toDelete = from g in db.MicroHard_EntitiesInGroups
                           where g.OrgUserID == userID && g.EntityType == (int)OwnerIDType.User
                           && groupIDsToDelete.Contains(g.OrgID)
                           select g;
            db.MicroHard_EntitiesInGroups.DeleteAllOnSubmit(toDelete);
            try
            {
                db.SubmitChanges();
            }
            catch (Exception ex)
            {
                rtn.ErrorMsg.Add("GroupImpl.DeleteUserInGroup", "从组中删除用户失败，请联系系统管理员");
                Log.Error("GroupImpl.DeleteUserInGroup", ex);
            }
            return rtn;
        }

        #endregion


        #region IRepository<Group> Members


        public Group GetModelByModel(Group model)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IRepository<Group> Members


        public ScopeResult scope
        {
            get;
            set;
        }

        #endregion

        #region IGroup Members
        private void GetSubGroupItem(MicroHard_Group group, ref TreeViewItem modelOrg)
        {
            if (group.GroupsChild == null || group.GroupsChild.Count == 0)
            {
                return;
            }
            modelOrg.Expanded = true;
            foreach (var o in group.GroupsChild)
            {
                modelOrg.Items.Add(new TreeViewItem
                {
                    Text = o.OrgName,
                    Value = o.OrgID.ToString(),
                });
                GetSubGroupItem(o, ref modelOrg);
            }
        }

        public List<TreeViewItem> GetGroup()
        {
            List<TreeViewItem> rtn = new List<TreeViewItem>();

            MicrohardOUGDBDataContext db = new MicrohardOUGDBDataContext();
            var list = db.MicroHard_Groups.Where(p => p.ParentOrgID == null).ToList();
            foreach (var o in list)
            {
                TreeViewItem toadd = new TreeViewItem
                {
                    Text = o.OrgName,
                    Value = o.OrgID.ToString()
                };
                GetSubGroupItem(o, ref toadd);
                rtn.Add(toadd);
            }
            return rtn;
        }

        #endregion

        #region IGroup Members


        public List<User> GetUserFromGroup(Guid groupID)
        {
            List<User> rtn = new List<User>();
            MicrohardOUGDBDataContext db = new MicrohardOUGDBDataContext();
            var users = (from u in db.MicroHard_EntitiesInGroups
                        from u2 in db.aspnet_Users
                        where u.OrgID == groupID && u.EntityType == (int)OwnerIDType.User
                        && u2.UserId == u.EntityID
                        select u2);
            var usersInRole = (from r in db.MicroHard_EntitiesInGroups
                               from u in db.aspnet_UsersInRoles
                               where u.RoleId == r.EntityID && r.EntityType == (int)OwnerIDType.Role
                               && r.OrgID == groupID
                               select u.aspnet_User);
            if (users.Count() > 0)
            {
                rtn.AddRange(users.Select(u => u.ToModel()).ToList());
            } if (usersInRole.Count() > 0)
            {
                rtn.AddRange(usersInRole.Select(u => u.ToModel()).ToList());
            }
            return rtn;
        }

        #endregion
    }
}
